package com.zycfc.zsf.boot.redis.util;

import com.zycfc.zsf.boot.redis.constant.*;
import com.zycfc.zsf.boot.util.time.*;
import com.zycfc.zsf.boot.localcache.cache.*;
import com.zycfc.zsf.boot.redis.domain.*;
import com.google.common.cache.*;
import com.zycfc.zsf.boot.util.text.*;
import com.zycfc.zsf.boot.util.collection.*;
import java.util.*;
import java.util.concurrent.*;
import org.slf4j.*;

public class RedisCallStatUtil
{
    private static final Logger log;
    
    public static void doRedisCallStat() {
        String cacheGroup = null;
        try {
            cacheGroup = RedisConstant.REDIS_CALL_STAT_CACHE_PRE + DateUtils.FORMAT_NO_SEP_ON_MINUTE.format(new Date(System.currentTimeMillis() - 60000L));
            final ConcurrentMap<String, Object> map = (ConcurrentMap<String, Object>)LocalCacheUtil.getAll(cacheGroup);
            if (map == null || map.size() <= 0) {
                return;
            }
            final Set<String> keySet = map.keySet();
            for (final String key : keySet) {
                final Object obj = map.get(key);
                if (obj == null) {
                    continue;
                }
                statData(cacheGroup, key, obj);
            }
            removeLowerCache(cacheGroup);
        }
        catch (Throwable e) {
            RedisCallStatUtil.log.error("Redis\u8c03\u7528\u7edf\u8ba1-cacheGroup:{}-\u53d1\u751f\u5f02\u5e38:", (Object)cacheGroup, (Object)e);
        }
    }
    
    private static void statData(final String cacheGroup, final String key, final Object obj) {
        try {
            final CopyOnWriteArrayList<RedisCallInf> list = (CopyOnWriteArrayList<RedisCallInf>)obj;
            if (list == null || list.size() <= 0) {
                return;
            }
            final String realKey = key.substring(0, key.lastIndexOf(","));
            final String operType = key.substring(key.lastIndexOf(",") + 1);
            long callTimes = 0L;
            double totalCallDur = 0.0;
            double totalValSize = 0.0;
            final RedisCallInf inf = list.get(0);
            long minValSize = inf.getValSize();
            long maxValSize = inf.getValSize();
            long minCallDur = inf.getCallDur();
            long maxCallDur = inf.getCallDur();
            long callDur = 0L;
            int valSize = 0;
            int effectiveTime = 0;
            final boolean writeOperFlag = !RedisConstant.OPER_TYPE_GET.equals(operType);
            for (final RedisCallInf redisCallInf : list) {
                callDur = redisCallInf.getCallDur();
                valSize = redisCallInf.getValSize();
                totalCallDur += callDur;
                totalValSize += valSize;
                ++callTimes;
                if (callDur < minCallDur) {
                    minCallDur = callDur;
                }
                if (callDur > maxCallDur) {
                    maxCallDur = callDur;
                }
                if (valSize < minValSize) {
                    minValSize = valSize;
                }
                if (valSize > maxValSize) {
                    maxValSize = valSize;
                }
                if (writeOperFlag) {
                    if (effectiveTime == -1) {
                        continue;
                    }
                    final int curEffectiveTime = (redisCallInf.getEffectiveTime() != null) ? redisCallInf.getEffectiveTime() : 0;
                    if (curEffectiveTime != -1 && (effectiveTime < 0 || curEffectiveTime <= effectiveTime)) {
                        continue;
                    }
                    effectiveTime = curEffectiveTime;
                }
            }
            final long avgCallDur = Math.round(totalCallDur / callTimes);
            final long avgValSize = Math.round(totalValSize / callTimes);
            final RedisCallInf redisCallInf2 = new RedisCallInf(cacheGroup, realKey, operType, callTimes, avgCallDur, avgValSize);
            redisCallInf2.setMinCallDur(minCallDur);
            redisCallInf2.setMaxCallDur(maxCallDur);
            redisCallInf2.setMinValSize(minValSize);
            redisCallInf2.setMaxValSize(maxValSize);
            if (writeOperFlag) {
                redisCallInf2.setEffectiveTime(effectiveTime);
            }
            RedisCallStatUtil.log.debug("Redis\u8c03\u7528\u7edf\u8ba1-cacheGroup:{}-key:{}-\u7edf\u8ba1\u7ed3\u679c:{}", new Object[] { cacheGroup, key, redisCallInf2.toString() });
            RedisCallStatUtil.log.warn(redisCallInf2.toString());
        }
        catch (Throwable e) {
            RedisCallStatUtil.log.error("Redis\u8c03\u7528\u7edf\u8ba1-cacheGroup:{}-key:{}-\u53d1\u751f\u5f02\u5e38:", new Object[] { cacheGroup, key, e });
        }
    }
    
    private static void removeLowerCache(final String cacheGroup) {
        final ConcurrentHashMap<String, Cache> cacheMap = (ConcurrentHashMap<String, Cache>)LocalCacheUtil.getAllCache();
        if (cacheMap == null || cacheMap.size() <= 0) {
            return;
        }
        final Iterator<Map.Entry<String, Cache>> iterator = cacheMap.entrySet().iterator();
        String key = null;
        while (iterator.hasNext()) {
            final Map.Entry<String, Cache> entry = iterator.next();
            key = entry.getKey();
            if (StringUtils.isEmpty(key)) {
                continue;
            }
            if (!key.startsWith(RedisConstant.REDIS_CALL_STAT_CACHE_PRE) || cacheGroup.compareTo(key) < 0) {
                continue;
            }
            iterator.remove();
            RedisCallStatUtil.log.warn("Redis\u8c03\u7528\u7edf\u8ba1-\u5df2\u5220\u9664\u65e0\u7528\u7edf\u8ba1cache:{}", (Object)key);
        }
        final Set<String> keySet = cacheMap.keySet();
        if (CollectionUtils.isEmpty((Collection)keySet)) {
            return;
        }
        int count = 0;
        for (final String cachekey : keySet) {
            if (StringUtils.isEmpty(cachekey)) {
                continue;
            }
            if (!cachekey.startsWith(RedisConstant.REDIS_CALL_STAT_CACHE_PRE)) {
                continue;
            }
            ++count;
        }
        RedisCallStatUtil.log.warn("Redis\u8c03\u7528\u7edf\u8ba1-\u5220\u9664\u65e0\u7528\u7edf\u8ba1cache\u540e,cacheMap\u4e2d\u5305\u542b\u7684Redis\u7edf\u8ba1cache\u6570\u91cf:{}", (Object)count);
    }
    
    static {
        log = LoggerFactory.getLogger((Class)RedisCallStatUtil.class);
    }
}
